import {Controller, Post, All, required} from '../decorator/router'
import mongoose from 'mongoose'
import {login, upload} from '../decorator/auth'
import {
  addFriend, delFriend,
  getFriends,
  getUserById,
  getUsersByKeywords,
  updateAge, updateEmail,
  updateNickname,
  updateSex
} from '../service/user'

const oss = require('../utils/oss')
const nodeUrl = require('url')
const User = mongoose.model('User')

@Controller('/users')
export class UserRouter {
  @Post('/check')
  @login
  async check(ctx, next) {
    let {username, nickname, email, sex, age, avatar, _id} = ctx.userInfo
    ctx.body = {
      result: 1,
      data: {username, nickname, email, avatar, _id, sex, age}
    }
  }

  @Post('/login')
  @required({
    body: ['username', 'password']
  })
  async login(ctx, next) {
    try {
      let form = ctx.request.body
      let doc = await User.findOne({username: form.username})
      if (!doc) {
        ctx.body = {
          result: 0,
          mes: '账号或密码错误'
        }
      } else {
        if (doc.isLocked) {
          ctx.body = {
            result: 0,
            mes: '您的操作过于频繁，请稍后再试！'
          }
          return
        }

        let match = await doc.comparePassword(form.password)
        if (match) {
          await doc.incLoginAttempts(true)
          ctx.session.userId = doc._id
          ctx.session.password = doc.password
          const {username, nickname, email} = doc
          ctx.body = {
            result: 1,
            mes: '登陆成功！',
            data: {username, nickname, email}
          }
        } else {
          await doc.incLoginAttempts()
          ctx.body = {
            result: 0,
            mes: '账号或密码错误'
          }
        }
      }
    } catch (err) {
      console.error(err)
      ctx.body = {
        result: 0,
        mes: err.message
      }
    }
  }

  @All('/logout')
  async logout(ctx, next) {
    ctx.session = null
    ctx.body = {
      result: 1,
      mes: '注销成功'
    }
  }

  @Post('/register')
  async register(ctx, next) {
    let form = ctx.request.body

    let user = new User({
      username: form.username,
      nickname: form.nickname,
      password: form.password,
      sex: Number(form.sex) === 1 ? 1 : 0,
      role: 'user'
    })
    try {
      await user.save()
      ctx.session.userId = user._id
      ctx.session.password = user.password
      const {username, nickname, email} = user
      ctx.body = {
        data: {username, nickname, email},
        result: 1,
        mes: '注册成功！'
      }
    } catch (err) {
      console.error(err)
      ctx.body = {
        result: 0,
        mes: err.message
      }
    }
  }

  @Post('/exist')
  async exist(ctx, next) {
    let user = await User.findOne({username: ctx.request.body.username})
    if (user) {
      ctx.body = {
        result: 1,
        data: {
          exist: 1
        }
      }
    } else {
      ctx.body = {
        result: 1,
        data: {
          exist: 0
        }
      }
    }
  }

  @Post('/avatar')
  @login
  @upload
  async avatar(ctx, next) {
    try {
      let file = await oss.put(`chat-user/${ctx.userInfo.username}/avatar.png`, ctx.request.files.file.path)
      let url = nodeUrl.parse(file.url)
      if (url.search) {
        url = url.href + '&_=' + Date.now()
      } else {
        url = url.href + '?_=' + Date.now()
      }
      await User.updateOne({username: ctx.userInfo.username}, {
        $set: {
          avatar: url
        }
      })
      ctx.body = {
        data: url,
        result: 1,
        mes: '更新成功'
      }
    } catch (err) {
      console.error(err)
      ctx.body = {
        result: 0,
        mes: err.message
      }
    }
  }

  @Post('/base')
  @login
  async base(ctx, next) {
    try {
      const {nickname, email, sex, age} = ctx.request.body
      await User.updateOne({_id: ctx.userInfo._id}, {
        $set: {
          nickname,
          email,
          sex,
          age
        }
      })
      ctx.body = {
        result: 1,
        mes: '更新成功'
      }
    } catch (err) {
      console.error(err)
      ctx.body = {
        result: 0,
        mes: err.message
      }
    }
  }

  @Post('/password')
  @required({
    body: ['oldpassword', 'password']
  })
  @login
  async password(ctx, next) {
    const {oldpassword, password} = ctx.request.body
    const user = ctx.userInfo
    try {
      if (user.isLocked) {
        return ctx.body = {
          result: 0,
          mes: '您的操作过于频繁，请稍后再试'
        }
      }
      let match = await user.comparePassword(oldpassword)
      if (match) {
        if (oldpassword === password) {
          ctx.body = {
            result: 0,
            mes: '新密码不能与原密码相同'
          }
        } else {
          user.set({password})
          await user.save()
          ctx.body = {
            result: 1,
            mes: '更新成功'
          }
        }
      } else {
        await user.incLoginAttempts()
        ctx.body = {
          result: 0,
          mes: '原密码错误'
        }
      }
    } catch (err) {
      console.error(err)
      ctx.body = {
        result: 0,
        mes: err.message
      }
    }
  }

  @Post('/getUsers')
  @login
  async getUsers(ctx, next) {
    ctx.body = {
      data: await getUsersByKeywords(ctx.session.userId, ctx.request.body.keywords || ''),
      result: 1,
      mes: '查询成功！'
    }
  }

  @Post('/addFriend')
  @login
  @required({
    body: ['id']
  })
  async addFriend(ctx, next) {
    ctx.body = {
      data: await addFriend(ctx.session.userId, ctx.request.body.id),
      result: 1,
      mes: '添加好友成功！'
    }
  }

  @Post('/deFriend')
  @login
  @required({
    body: ['id']
  })
  async delFriend(ctx, next) {
    await delFriend(ctx.session.userId, ctx.request.body.id)
    ctx.body = {
      result: 1,
      mes: '删除好友成功'
    }
  }

  @Post('/getMyFriends')
  @login
  async getMyFriends(ctx, next) {
    const data = await getFriends(ctx.session.userId)
    ctx.body = {
      data: data.friends || [],
      result: 1,
      mes: '查询成功'
    }
  }

  @Post('/getUser')
  @login
  @required({
    body: ['id']
  })
  async getUser(ctx, next) {
    ctx.body = {
      data: await getUserById(ctx.request.body.id, ctx.session.userId),
      result: 1,
      mes: '查询成功'
    }
  }

  @Post('/nickname')
  @login
  @required({
    body: ['nickname']
  })
  async updateNickname(ctx, next) {
    ctx.body = {
      data: await updateNickname(ctx.session.userId, ctx.request.body.nickname),
      result: 1,
      mes: '修改昵称成功'
    }
  }

  @Post('/sex')
  @login
  @required({
    body: ['sex']
  })
  async updateSex(ctx, next) {
    ctx.body = {
      data: await updateSex(ctx.session.userId, ctx.request.body.sex),
      result: 1,
      mes: '修改成功!'
    }
  }

  @Post('/age')
  @login
  @required({
    body: ['age']
  })
  async updateAge(ctx, next) {
    ctx.body = {
      data: await updateAge(ctx.session.userId, ctx.request.body.age),
      result: 1,
      mes: '修改成功！'
    }
  }

  @Post('/email')
  @login
  @required({
    body: ['email']
  })
  async updateEmail(ctx, next) {
    ctx.body = {
      data: await updateEmail(ctx.session.userId, ctx.request.body.email),
      result: 1,
      mes: '修改成功！'
    }
  }
}